package ui;

/**
 * TranslatorFrame.java
 *
 * Copyright (C) 2009,  Richard Midwinter
 * 
 * This file is part of google-api-translate-java.
 *
 * google-api-translate-java is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * google-api-translate-java is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with google-api-translate-java.  If not, see <http://www.gnu.org/licenses/>.
 */

/*
 * TranslatorFrame.java
 *
 * Created on 03 February 2008, 19:47
 */
import grabNtrans.GrabSub;

import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JTextArea;
import javax.swing.TransferHandler;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.JTextComponent;
import javax.swing.text.Position;

import org.apache.xmlrpc.XmlRpcException;
import org.apache.xmlrpc.client.XmlRpcClient;
import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;

import utils.Common;
import utils.ListFiles;
import utils.OpenSubtitlesHasher;

import com.google.api.Files;
import com.google.api.translate.Language;
import com.google.api.translate.Translate;

/**
 *
 * @author rich.midwinter
 */
public class Frame extends javax.swing.JFrame {
    
    /**
         * Serial version UID.
         */
        private static final long serialVersionUID = 7916697355146649532L;
        
        private static final String REFERRER_PATH = System.getProperty("user.home") +"/.gtReferrer";
        
        private Language languageFrom = Language.AUTO_DETECT;
        private Language languageTo = Language.ENGLISH;
        
        /** Creates new form TranslatorFrame 
         * @throws XmlRpcException */
    public Frame() throws IOException, XmlRpcException {
        initComponents();
        setLocationRelativeTo(null);
        
        String referrer = null;
        
        final File ref = new File(REFERRER_PATH);
        if (ref.exists()) {
                referrer = Files.read(ref).trim();
        } else {
                referrer = (String) JOptionPane.showInputDialog(this,
                                "Please enter the address of your website.\n(This is just to help Google identify how their translation tools are used).",
                                "Website address", JOptionPane.OK_OPTION);
                Files.write(ref, referrer);
        }
        
        if (referrer.length() > 0) {
                Translate.setHttpReferrer(referrer);
        } else {
                System.exit(1);
        }
    }
    
    private void translate() {
        try {
            toTextArea.setText(Translate.translate(fromTextArea.getText().trim(), languageFrom, languageTo));
        } catch (Exception ex) {
            Logger.getLogger(Frame.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    /**
     * This method is called from within the constructor to
     * initialize the form.
     * @throws MalformedURLException 
     * @throws XmlRpcException 
     */
    private void initComponents() throws MalformedURLException, XmlRpcException {
        buttonGroup1 = new javax.swing.ButtonGroup();
        buttonGroup2 = new javax.swing.ButtonGroup();
        jPanel2 = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        fromTextArea = new javax.swing.JTextArea();
        jPanel3 = new javax.swing.JPanel();
        jScrollPane2 = new javax.swing.JScrollPane();
        toTextArea = new javax.swing.JTextArea();
        jMenuBar1 = new javax.swing.JMenuBar();
        jMenu1 = new javax.swing.JMenu();
        jMenuItem1 = new javax.swing.JMenuItem();
        jMenuItem2 = new javax.swing.JMenuItem();
        jMenuTo = new javax.swing.JMenu();
        jMenuFrom = new javax.swing.JMenu();
        fc = new JFileChooser();
        gs = new GrabSub();
        XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
		config.setServerURL(new URL("http://api.opensubtitles.org/xml-rpc"));
		client = new XmlRpcClient();
		client.setConfig(config);
		token = (String) ((HashMap) client.execute("LogIn",
				new Object[] { "", "", "en", "OS Test User Agent" }))
				.get("token");
		oshash = new OpenSubtitlesHasher();
        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Translator");
        getContentPane().setLayout(new javax.swing.BoxLayout(getContentPane(), javax.swing.BoxLayout.PAGE_AXIS));

        fromTextArea.setColumns(20);
        fromTextArea.setEditable(false);
        fromTextArea.setLineWrap(true);
        fromTextArea.setRows(5);
        fromTextArea.setWrapStyleWord(true);
        fromTextArea.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                fromTextAreaKeyPressed(evt);
            }
        });
        FileAndTextTransferHandler transferHandler = new FileAndTextTransferHandler();        fromTextArea.setDragEnabled(true);
        fromTextArea.setTransferHandler(transferHandler);
        jScrollPane1.setViewportView(fromTextArea);

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 309, Short.MAX_VALUE)
                .addContainerGap())
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 93, Short.MAX_VALUE)
                .addContainerGap())
        );

        getContentPane().add(jPanel2);

        toTextArea.setColumns(20);
        toTextArea.setEditable(false);
        toTextArea.setLineWrap(true);
        toTextArea.setRows(5);
        toTextArea.setWrapStyleWord(true);
        jScrollPane2.setViewportView(toTextArea);

        javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
        jPanel3.setLayout(jPanel3Layout);
        jPanel3Layout.setHorizontalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 309, Short.MAX_VALUE)
                .addContainerGap())
        );
        jPanel3Layout.setVerticalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 93, Short.MAX_VALUE)
                .addContainerGap())
        );

        getContentPane().add(jPanel3);

        jMenu1.setText("File");
        jMenuItem2.setText("Open");
        jMenuItem2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem2ActionPerformed(evt);
            }
        });
        
    	
        jMenuItem1.setText("Exit");
        jMenuItem1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem1ActionPerformed(evt);
            }
        });
        jMenu1.add(jMenuItem2);
        jMenu1.add(jMenuItem1);

        jMenuBar1.add(jMenu1);

        jMenuFrom.setText("From");
        jMenuTo.setText("To");
        
        for (final Language language : Language.values()) {
                JRadioButtonMenuItem menuItem = new JRadioButtonMenuItem();
                menuItem.setText(language.name());
                if (language.equals(languageFrom)) {
                        menuItem.setSelected(true);
                }
                menuItem.addActionListener(new ActionListener() {
                        public void actionPerformed(final ActionEvent evt) {
                                languageFrom = language;
                        }
                });
                buttonGroup1.add(menuItem);
                jMenuFrom.add(menuItem);
                
                if (language != Language.AUTO_DETECT) {
                        menuItem = new JRadioButtonMenuItem();
                        menuItem.setText(language.name());
                        if (language.equals(languageTo)) {
                                menuItem.setSelected(true);
                        }
                        menuItem.addActionListener(new ActionListener() {
                                public void actionPerformed(final ActionEvent evt) {
                                        languageTo = language;
                                }
                        });
                        buttonGroup2.add(menuItem);
                        jMenuTo.add(menuItem);
                }
        }

        jMenuBar1.add(jMenuFrom);
        jMenuBar1.add(jMenuTo);

        setJMenuBar(jMenuBar1);

        pack();
    }

    private void jMenuItem1ActionPerformed(java.awt.event.ActionEvent evt) {
        System.exit(0);
    }

    private void jMenuItem2ActionPerformed(java.awt.event.ActionEvent evt) {
    	fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
    	int returnVal = fc.showOpenDialog(jMenuItem2);
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            File path = fc.getSelectedFile();
            Vector<File> fileArray = new Vector<File>();
            ListFiles.list(true, path, fileArray);
            
            for (File file : fileArray) {
            	try {
            	Vector para = new Vector();
        		HashMap movInfo = new HashMap();
        		
        		movInfo.put("sublanguageid", "all");
        		
       		 	movInfo.put("moviehash", oshash.computeHash(file));
       		 	movInfo.put("moviebytesize", String.valueOf(file.length()));
       		 	movInfo.put("query", Common.noExtensions(file.getName()));
       		 	para.add(movInfo);
					if (gs.grabSub(client, token, para, file))
						toTextArea.append(file.getName()
										+ "'s sub found \n-----------------------------------------");
					else
						toTextArea
						.append("Sorry " + file.getName()
										+ "'s did not found\n------------------------------------------");

				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
            }
            //This is where a real application would open the file.
        } else {
           System.out.println("Cancel");
        }
    }
    private void fromTextAreaKeyPressed(java.awt.event.KeyEvent evt) {
        if (evt.getKeyCode() == KeyEvent.VK_ENTER) {
            translate();
            evt.consume();
        }
    }
    
    /**
     * @param args the command line arguments
     */
	public static void main(String args[]) {
		java.awt.EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					new Frame().setVisible(true);
				} catch (IOException e) {
					e.printStackTrace();
				} catch (XmlRpcException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		});
	}
	class FileAndTextTransferHandler extends TransferHandler {
		  private DataFlavor fileFlavor, stringFlavor;


		  private JTextArea source;

		  private boolean shouldRemove;

		  protected String newline = "\n";

		  //Start and end position in the source text.
		  //We need this information when performing a MOVE
		  //in order to remove the dragged text from the source.
		  Position p0 = null, p1 = null;

		  FileAndTextTransferHandler() {
		    
		    fileFlavor = DataFlavor.javaFileListFlavor;
		    stringFlavor = DataFlavor.stringFlavor;
		  }

		  public boolean importData(JComponent c, Transferable t) {
		    JTextArea tc;

		    if (!canImport(c, t.getTransferDataFlavors())) {
		      return false;
		    }
		    //A real application would load the file in another
		    //thread in order to not block the UI. This step
		    //was omitted here to simplify the code.
		    try {
		      if (hasFileFlavor(t.getTransferDataFlavors())) {
		        String str = null;
		        java.util.List files = (java.util.List) t
		            .getTransferData(fileFlavor);
		        for (int i = 0; i < files.size(); i++) {
		          File file = (File) files.get(i);
		          //Tell the tabbedpane controller to add
		          //a new tab with the name of this file
		          //on the tab. The text area that will
		          //display the contents of the file is returned.

		          BufferedReader in = null;

		          try {
		            in = new BufferedReader(new FileReader(file));

		          } catch (IOException ioe) {
		            System.out
		                .println("importData: Unable to read from file "
		                    + file.toString());
		          } finally {
		            if (in != null) {
		              try {
		                in.close();
		              } catch (IOException ioe) {
		                System.out
		                    .println("importData: Unable to close file "
		                        + file.toString());
		              }
		            }
		          }
		        }
		        return true;
		      } else if (hasStringFlavor(t.getTransferDataFlavors())) {
		        tc = (JTextArea) c;
		        if (tc.equals(source)
		            && (tc.getCaretPosition() >= p0.getOffset())
		            && (tc.getCaretPosition() <= p1.getOffset())) {
		          shouldRemove = false;
		          return true;
		        }
		        String str = (String) t.getTransferData(stringFlavor);
		        tc.replaceSelection(str);
		        return true;
		      }
		    } catch (UnsupportedFlavorException ufe) {
		      System.out.println("importData: unsupported data flavor");
		    } catch (IOException ieo) {
		      System.out.println("importData: I/O exception");
		    }
		    return false;
		  }

		  protected Transferable createTransferable(JComponent c) {
		    source = (JTextArea) c;
		    int start = source.getSelectionStart();
		    int end = source.getSelectionEnd();
		    Document doc = source.getDocument();
		    if (start == end) {
		      return null;
		    }
		    try {
		      p0 = doc.createPosition(start);
		      p1 = doc.createPosition(end);
		    } catch (BadLocationException e) {
		      System.out
		          .println("Can't create position - unable to remove text from source.");
		    }
		    shouldRemove = true;
		    String data = source.getSelectedText();
		    return new StringSelection(data);
		  }

		  public int getSourceActions(JComponent c) {
		    return COPY_OR_MOVE;
		  }

		  //Remove the old text if the action is a MOVE.
		  //However, we do not allow dropping on top of the selected text,
		  //so in that case do nothing.
		  protected void exportDone(JComponent c, Transferable data, int action) {
		    if (shouldRemove && (action == MOVE)) {
		      if ((p0 != null) && (p1 != null)
		          && (p0.getOffset() != p1.getOffset())) {
		        try {
		          JTextComponent tc = (JTextComponent) c;
		          tc.getDocument().remove(p0.getOffset(),
		              p1.getOffset() - p0.getOffset());
		        } catch (BadLocationException e) {
		          System.out.println("Can't remove text from source.");
		        }
		      }
		    }
		    source = null;
		  }

		  public boolean canImport(JComponent c, DataFlavor[] flavors) {
		    if (hasFileFlavor(flavors)) {
		      return true;
		    }
		    if (hasStringFlavor(flavors)) {
		      return true;
		    }
		    return false;
		  }

		  private boolean hasFileFlavor(DataFlavor[] flavors) {
		    for (int i = 0; i < flavors.length; i++) {
		      if (fileFlavor.equals(flavors[i])) {
		        return true;
		      }
		    }
		    return false;
		  }

		  private boolean hasStringFlavor(DataFlavor[] flavors) {
		    for (int i = 0; i < flavors.length; i++) {
		      if (stringFlavor.equals(flavors[i])) {
		        return true;
		      }
		    }
		    return false;
		  }
		}
    // Variables declaration
    private javax.swing.ButtonGroup buttonGroup1;
    private javax.swing.ButtonGroup buttonGroup2;
    private javax.swing.JTextArea fromTextArea;
    private javax.swing.JMenu jMenu1;
   
    private JFileChooser fc ;
    private javax.swing.JMenu jMenuFrom;
    private javax.swing.JMenu jMenuTo;
    private javax.swing.JMenuBar jMenuBar1;
    private javax.swing.JMenuItem jMenuItem1;
    private javax.swing.JMenuItem jMenuItem2;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JTextArea toTextArea;
    private String dir;
    private GrabSub gs;
    private String token;
    private XmlRpcClient client;
    private OpenSubtitlesHasher oshash;
    // End of variables declaration   
}
